/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package teste;

import config.LogErro;
import controllers.AtributoAuxController;
import controllers.DimensaoController;
import controllers.JdbcAuxController;
import controllers.JdbcDimController;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JOptionPane;
import models.dados.HibernateUtil;
import models.dados.JdbcDAO;
import models.entidades.Procedimento;
import views.utilitario.ResultadoTestes;

/**
 *
 * @author Wenderson
 */
public class ExecutarTestes {   
    private  ResultadoTestes resultadoTestes = null;
    private  ArrayList<ResultadoTestes> listaResult = new ArrayList<ResultadoTestes>();
    
    private  Procedimento procedimento;
    private  HashMap<String, String> chaves;
    private  HashMap<String, String> atrAux;
    private  HashMap<String, String> atrNaoChaves;
    private  HashMap<String, String> atrNaoChavesNull;
    private  HashMap<String, String> atrNaoChavesChar;
    
    private  Testes testes;
    
    private StringBuilder sb;
    
    public  ArrayList<ResultadoTestes> executarTestes(Procedimento p, ArrayList<Boolean> lista) {
        procedimento = p;
        testes = new Testes(procedimento);

        listaResult = null;
        listaResult = new ArrayList<ResultadoTestes>();
        
        sb = null;
        sb = new StringBuilder("                DADOS DA EXECUÇÃO DOS TESTES\n\n\n");
        
        efetuarTestes(lista);
        
        //System.out.println(sb.toString());
        ManipulaArquivo.inserirArquivo(sb.toString());
        
        return listaResult;
    }
    
    private  ArrayList<ResultadoTestes> efetuarTestes(ArrayList<Boolean> lista) {
        try {
            if (lista.get(0)) {
                //System.out.println("1a");
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 001", ""));
                teste1A();
                sb.append(String.format("\n\n%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 001", ""));
            }
            
            if (lista.get(1)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 002", ""));
                //System.out.println("1b");
                teste1B();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 002", ""));
            }
            
            if (lista.get(2)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 003", ""));
                //System.out.println("1c");
                teste1C();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 003", ""));
            }
            
            if (lista.get(3)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 004", ""));
                //System.out.println("2");
                teste2();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 004", ""));
            }
            
            if (lista.get(4)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 005", ""));
                //System.out.println("3a");
                teste3A();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 005", ""));
            }
            
            if (lista.get(5)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 006", ""));
                //System.out.println("3b");
                teste3B();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 006", ""));
            }
            
            if (lista.get(6)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 007", ""));
                //System.out.println("4a");
                teste4A();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 007", ""));
            }
            
            if (lista.get(7)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 008", ""));
                //System.out.println("4b");
                teste4B();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 008", ""));
            }
            
            if (lista.get(8)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 009", ""));
                //System.out.println("4c");
                teste4C();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 009", ""));
            }
            
            if (lista.get(9)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 010", ""));
                //System.out.println("4d");
                teste4D();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 010", ""));
            }
            
            if (lista.get(10)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 011", ""));
                //System.out.println("4e");
                teste4E();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 011", ""));
            }
            
            if (lista.get(11)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 012", ""));
                //System.out.println("4f");
                teste4F();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 012", ""));
            }
            
            if (lista.get(12)) {
                sb.append(String.format("%-10s%s%10s\n\n", "", "CASO DE TESTE 013", ""));
                //System.out.println("5");
                teste5();
                sb.append(String.format("%-10s%s%10s\n\n", "", "FIM CASO DE TESTE 013", ""));
            }
            
            System.out.println(lista.toString());
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
        return null;
    }
    
    public ArrayList<String> listaErros() {
        return testes.listaErros();
    }
    
    private  void teste1A() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, quantidade);
            executarProcedimento();
            
            resultado = testes.teste1A();
            
            listaResult.add(getResultado(resultado, "TC_001"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }

    private JdbcDAO j = new JdbcDAO();
    
    private void executarProcedimento() {
        ManipulaBanco.executarProcedimento(procedimento);
        
        //System.out.println(j.resultadoTabela(procedimento.getTabAux().getEsquema(), procedimento.getTabAux().getNome()));
        //System.out.println("\n\n");
        sb.append(j.resultadoTabela(procedimento.getTabAux().getEsquema(), procedimento.getTabAux().getNome()));
        sb.append("\n\n");
        sb.append(j.resultadoTabela(procedimento.getDimensao().getEsquema(), procedimento.getDimensao().getNome()));
        sb.append("\n\n");
        //System.out.println(j.resultadoTabela(procedimento.getDimensao().getEsquema(), procedimento.getDimensao().getNome()));
        //System.out.println("\n\n\n\n");
    }
    
    private  void teste1B() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, quantidade);
            executarProcedimento();
            
            resultado = testes.teste1B();
            
            listaResult.add(getResultado(resultado, "TC_002"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste1C() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, quantidade);
            executarProcedimento();
            
            resultado = testes.teste1C();
            
            listaResult.add(getResultado(resultado, "TC_003"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste2() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, quantidade);
            executarProcedimento();
            executarProcedimento();
            
            resultado = testes.teste2();
            
            listaResult.add(getResultado(resultado, "TC_004"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste3A() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChaves = getAtrNaoChaves(1);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            resultado = testes.teste3A();
            
            listaResult.add(getResultado(resultado, "TC_005"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    public  void teste3B() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChaves = getAtrNaoChaves(1);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            resultado = testes.teste3B(5);
            
            listaResult.add(getResultado(resultado, "TC_006"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste4A() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChaves = getAtrNaoChaves(2);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            resultado = testes.teste4A();
            
            listaResult.add(getResultado(resultado, "TC_007"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste4B() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChaves = getAtrNaoChaves(2);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            resultado = testes.teste4B(10);
            
            listaResult.add(getResultado(resultado, "TC_008"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste4C() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChaves = getAtrNaoChaves(2);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            resultado = testes.teste4C();
            
            listaResult.add(getResultado(resultado, "TC_009"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste4D() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChaves = getAtrNaoChaves(2);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            resultado = testes.teste4D();
            
            listaResult.add(getResultado(resultado, "TC_010"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste4E() {
        HashMap<String, ArrayList<Object>> inserts = null;
        HashMap<String, ArrayList<Object>> insertsNull = null;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChavesNull = getAtrNaoChavesNull(2, 1);
            
            // CASO NÃO EXISTA ATRIBUTOS QUE POSSAM ACEITAR VALORES NULOS
            if (atrNaoChavesNull == null || atrNaoChavesNull.isEmpty()) {
                resultadoTestes = getResultado(false, "TC_011");
                listaResult.add(resultadoTestes);
                ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
                return;
            }
            
            for (String atributo : atrNaoChavesNull.keySet()) {
                insertsNull = GeradorDados.alterarValoresNull(inserts, atributo);
            }
            
            if (insertsNull != null && insertsNull.size() > 0) {
                ManipulaBanco.inserirDados(procedimento, insertsNull, quantidade);
                executarProcedimento();

                resultado = testes.teste4E(insertsNull, quantidade);
            } else {
                resultado = false;
            }                                

            if (resultado) {
                ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());

                ManipulaBanco.inserirDados(procedimento, insertsNull, quantidade);
                executarProcedimento();

                int countAntes = JdbcDimController.count(procedimento.getDimensao().getEsquema(), procedimento.getDimensao().getNome());

                ManipulaBanco.inserirDados(procedimento, inserts, quantidade);
                executarProcedimento();

                int countDepois = JdbcDimController.count(procedimento.getDimensao().getEsquema(), procedimento.getDimensao().getNome());

                if ((countAntes * 2) == countDepois) { 
                    ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());

                    ManipulaBanco.inserirDados(procedimento, inserts, quantidade);
                    executarProcedimento();

                    countAntes = JdbcDimController.count(procedimento.getDimensao().getEsquema(), procedimento.getDimensao().getNome());

                    ManipulaBanco.inserirDados(procedimento, insertsNull, quantidade);
                    executarProcedimento();
                    

                    countDepois = JdbcDimController.count(procedimento.getDimensao().getEsquema(), procedimento.getDimensao().getNome());

                    if ((countAntes * 2) == countDepois) { 
                        resultadoTestes = getResultado(true, "TC_011");
                    } else {
                        resultadoTestes = getResultado(false, "TC_011");
                    }
                } else {
                    resultadoTestes = getResultado(false, "TC_011");
                }
            } else {
                resultadoTestes = getResultado(false, "TC_011");
            }
            
            listaResult.add(resultadoTestes);
            resultadoTestes = null;
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste4F() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            atrNaoChavesChar = getAtrNaoChavesChar(2);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, quantidade);
            executarProcedimento();
            
            for (String atributo : atrNaoChavesChar.keySet()) {
                inserts = GeradorDados.alterarValoresCharacter(inserts, atributo, GeradorDados.FonteTexto.ALTA);
            }
            
            resultado = testes.teste4F(inserts, quantidade);
            
            listaResult.add(getResultado(resultado, "TC_012"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    private  void teste5() {
        HashMap<String, ArrayList<Object>> inserts;
        int quantidade = 10;
        boolean resultado = false;
        
        try {
            atrAux = getAtributosAux();
            inserts = GeradorDados.getValores(procedimento, atrAux, quantidade);
            
            ManipulaBanco.deletarDadosDimensao(procedimento.getDimensao());
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            atrNaoChaves = getAtrNaoChaves(2);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            atrNaoChaves = getAtrNaoChaves(1);
            
            for (String atributo : atrNaoChaves.keySet()) {
                inserts = GeradorDados.alterarValores(inserts, atributo, 5, 5);
            }
            
            ManipulaBanco.inserirDados(procedimento, inserts, 5);
            executarProcedimento();
            
            resultado = testes.teste5();
            
            listaResult.add(getResultado(resultado, "TC_013"));
        } catch (Exception e) {
            LogErro.gravaErro(e);e.printStackTrace();
        }
    }
    
    //<editor-fold defaultstate="collapsed" desc="Get Chaves e Atributos">
    private  ResultadoTestes getResultado(boolean resultado, String teste) {
        ResultadoTestes resultadoTestes;
        
        if (resultado) {
            System.out.println("OK " + teste);
            resultadoTestes = new ResultadoTestes("OK", teste);
        } else {
            System.out.println("ERRO " + teste);
            resultadoTestes = new ResultadoTestes("ERRO", teste);
        }
        
        return resultadoTestes;
    }
    
    private  HashMap<String, String> getAtributosAux() {
        if (atrAux == null || atrAux.isEmpty()) {
            atrAux = AtributoAuxController.getNomeTipo(procedimento);
        }
        // System.out.println("RESULTADO: " + atrAux.toString());
        return atrAux;
    }
    
    private  HashMap<String, String> getChaves() {
        if (chaves == null || chaves.isEmpty()) {
            chaves = AtributoAuxController.getChavesReferenciadas(procedimento);
        }
        
        return chaves;
    }
    
    private  HashMap<String, String> getAtrNaoChaves(int tipo_atributo) {
        atrNaoChaves = AtributoAuxController.getAtributosNaoChaves(procedimento, tipo_atributo);
        
        return atrNaoChaves;
    }
    
    private  HashMap<String, String> getAtrNaoChavesNull(int tipo_atributo, int nulidade) {
        if (atrNaoChavesNull == null || atrNaoChavesNull.isEmpty()) {
            atrNaoChavesNull = AtributoAuxController.getAtributosNaoChavesNull(procedimento, tipo_atributo, nulidade);
        }
        
        return atrNaoChavesNull;
    }
    
    private  HashMap<String, String> getAtrNaoChavesChar(int tipo_atributo) {
        if (atrNaoChavesChar == null || atrNaoChavesChar.isEmpty()) {
            atrNaoChavesChar = AtributoAuxController.getAtributosNaoChavesChar(procedimento, tipo_atributo);
        }
        
        return atrNaoChavesChar;
    }
    
    //</editor-fold>    
}
